perm filename BIGNUM.MAC[LSP,BGB] blob
sn#000717 filedate 1972-11-12 generic text, type T, neo UTF8
00100 TITLE BIGNUM ARITHMETIC
00200
00300 ;AC DEFINITIONS
00400 NIL=0
00500 A=1
00600 B=2
00700 C=3
00800 T=6
00900 TT=7
01000 T10=10
01100 FF=16
01200 AR1=4
01300 F=15
01400 P=14
01500 D=12
01600 S=11
01700 AR2A=5
01800 R=13
01900 SP=17
02000
02100 INUMIN=377777
02200 INUM0=577777
02300 SIGN=400000
02400 MINSGN==10
02500
02600 INTERNAL BIGINI
02650 INTERNAL .COPY,.Q1,MAKBIG,POPAJ ;SOLELY FOR GFPAK* <A.HEARN>
02700
02800 EXTERNAL CONS,FWCONS,ACONS,NCONS,XCONS,VBASE,VNOPOINT,LAST,NUMVAL
02900 EXTERNAL POSNUM,NEGNUM,NUM1,CTY,EVBIG,REVERSE,BPR
03000 EXTERNAL TRUE,FALSE,NUMV2,FIXNUM,FLONUM,FIX1A,LENGTH,MINUSP
03100 EXTERNAL BPR,NUM3,EVBIG,NUMV4,OPOV,NUMV3,NUMBP2,FIX2,OPR,FLOOV
03200 PAGE
03300 ;POWER OF TEN
03400 PWR10: MOVEM B,BASEX#
03500 MOVE C,B
03600 IMUL B,B ;BASE↑2
03700 IMUL B,B ;BASE↑4
03800 IMUL B,C ;BASE↑5
03900 IMUL B,B ;BASE↑TEN
04000 MOVEM B,BASE10#
04100 POPJ P,
04200
04300 B0CONS: MOVEI A,0
04400 BNCONS: MOVEI B,0
04500 BCONS: PUSHJ P,FWCONS
04600 JRST CONS
04700
04800 QCONS=ACONS-1
04900 PAGE
05000 ;INITIALIZE THE BIGNUM SYSTEM BY CHANGING MAGIC LOCATIONS IN LISP
05100 BIGINI: MOVE A,[JRST BPRINT]
05200 MOVEM A,BPR ;PRINT
05300 HRRI A,BIGEV
05400 MOVEM A,EVBIG ;EVAL
05500 HRRI A,NUMVB
05600 MOVEM A,NUMV4 ;NUMVAL
05700 HRRI A,BIGDIS
05800 MOVEM A,NUMV3 ;BIGNUM OPS
05900 HRRI A,BIGNP
06000 MOVEM A,NUMBP2 ;NUMBERP
06100 HRRI A,RDBNM
06200 HRRM A,NUM3 ;READ
06300 HRRI A,FIXOVL
06400 HRRM A,OPOV ;OVERFLOW
06500 HRRI A,BFIX
06600 HRRM A,FIX2 ;FIX
06700 JRST FALSE
06800 PAGE
06900 ;BIGNUM PRINT
07000 ;BPR IN LISP IS JRST BPRINT
07100 BPRINT: CAIN B,POSNUM
07200 JRST BPRIN2
07300 CAIE B,NEGNUM
07400 JRST BPR+1
07500 XCT "-",CTY
07600 BPRIN2: PUSHJ P,COPY
07700 PUSHJ P,BPRI
07800 POPJ P,
07900
08000 BPRI: MOVE B,VBASE
08100 SUBI B,INUM0
08200 PUSHJ P,PWR10
08300 PUSHJ P,BPRJ
08400 SKIPE A,VNOPOINT
08500 POPJ P,
08600 MOVE A,BASEX
08700 CAIE A,12
08800 POPJ P,
08900 MOVEI A,"."
09000 JRST (R) ;PARTICULAR TYO
09100
09200 BPRJ: MOVE B,BASE10
09300 PUSHJ P,Q1
09400 JUMPE B,BPR2 ;ZERO QUOTIENT
09500 PUSH P,A ;REMAINDER
09600 MOVE A,B ;QUOTIENT
09700 PUSHJ P,BPRJ
09800 POP P,A ;REMAINDER
09900
10000 BPR1: MOVEI C,12 ;PRINT TEN DIGITS
10100 SOJL C,CPOPJ
10200 IDIV A,BASEX
10300 HRLM B,(P)
10400 PUSHJ P,BPR1+1
10500 JRST FP7A1 ;PARTICULAR TYO FOR DIGIT
10600
10700 ;IGNORE LEADING ZERO DIGITS FOR FIRST WORD
10800 BPR2: JUMPE A,CPOPJ
10900 IDIV A,BASEX
11000 HRLM B,(P)
11100 PUSHJ P,BPR2
11200 FP7A1: HLRE A,(P)
11300 ADDI A,"0"
11400 JRST (R) ;PARTICULAR TYO FOR DIGIT
11500
11600 PAGE
11700 ;DIVIDES BIGNUM IN A BY INTEGER IN B
11800 ;DESTROYS ORIGINAL BIGNUM
11900 ;RETURNS REMAINDER IN A, QUOTIENT IN B
11950 .Q1:
12000 Q1: MOVEM B,Y#
12100 PUSH P,A
12200 HRRZ A,(A)
12300 JUMPE A,Q1A
12400 PUSHJ P,Q1+1
12500 POP P,C
12600 HRRM B,(C)
12700 HLRZ T,(C)
12800 MOVE B,(T)
12900 DIV A,Y
13000 Q1B: MOVEM A,(T) ;REPLACE OLD DIGIT
13100 MOVE A,B
13200 MOVE B,C
13300 POPJ P,
13400
13500 Q1A: POP P,C
13600 HLRZ T,(C)
13700 MOVE A,(T)
13800 IDIV A,Y
13900 JUMPN A,Q1B ;NON-ZERO QUOTIENT - KEEP IT
14000 HRRZM FF,(T) ;RECLAIM FULL WORD
14100 MOVE FF,T
14200 HRRZM F,(C) ;RECLAIM FREE WORD
14300 HRRZ F,C
14400 MOVEI C,0
14500 JRST Q1B+1
14600 PAGE
14700 ;BIGNUM READ
14800 ;NUM3 IN LISP HAS JFCL 10,RDBNM
14900 RDBNM: PUSH P,[NIL] ;INITIAL VALUE OF BIGNUM
15000 MOVSI C,700
15100 HRRI C,(SP) ;BYPE POINTER TO SPEC PDL
15200 MOVEM T,TSAV#
15300 MOVEM C,RDPTR#
15400 HRRZ B,NUM1 ;BASE OF NUMBER
15500 PUSHJ P,PWR10
15600
15700 RDNM1: MOVEI C,12 ;TEN DIGITS AT A TIME
15800 MOVEI A,0
15900 ILDB B,RDPTR
16000 JUMPE B,RDNM2 ;END OF BIGNUM
16100 IMUL A,BASEX
16200 ADDI A,-"0"(B)
16300 SOJG C,.-4
16400 MOVE B,BASE10
16500 PUSHJ P,RDSUB
16600 JRST RDNM1
16700
16800 RDNM2: CAIN C,12 ;NO DIGITS IN LAST SUPERDIGIT
16900 JRST RDNM3
17000 HRREI C,-12(C) ;NUMBER OF DIGITS IN LAST
17100 MOVEI B,1
17200 IMUL B,BASEX
17300 AOJL C,.-1 ;COMPUTE BASEX↑(NUMBER OF DIGITS)
17400 PUSHJ P,RDSUB
17500 RDNM3: MOVEI B,POSNUM
17600 MOVE T,TSAV
17700 TLNE T,MINSGN ;SIGN OF BIGNUM
17800 MOVEI B,NEGNUM
17900 POP P,A
18000 SUB P,[XWD 1,1]
18100 JRST QCONS
18200
18300 RDSUB: MOVE C,-1(P)
18400 PUSHJ P,BTIME1 ;BIGNUM(C)*INT(B)+INT(A)
18500 MOVEM A,-1(P)
18600 POPJ P,
18700 PAGE
18800 BTIME0: PUSH P,B
18900 PUSHJ P,COPY
19000 MOVE C,A
19100 POP P,B
19200 MOVEI A,0
19300
19400 ;BIG(C)*INT(B)+INT(A)
19500 BTIME1: JUMPE C,BNCONS ;END OF BIGNUM
19600 MOVEM B,MULR# ;MULTIPLIER
19700 PUSH P,C ;BIGNUM
19800 BT1B: MOVEM A,CARRY#
19900 MOVS T,(C)
20000 MOVE A,(T)
20100 MUL A,MULR
20200 ADD B,CARRY
20300 TLZE B,SIGN
20400 ADDI A,1
20500 BT1E: MOVEM B,(T) ;STORE LOW ORDER PRODUCT+CARRY IN BIGNUM
20600 HLRZS T ;(CDR BIGNUM)
20700 JUMPE T,BT1C ;END OF BIGNUM
20800 MOVE C,T
20900 JRST BT1B
21000
21100 BT1C: JUMPE A,POPAJ ;NO HIGH ORDER PART
21200 PUSHJ P,BNCONS ;CONSES FOR REMAINING HIGH ORDER PART
21300 HRRM A,(C) ;RPLACD END OF BIGNUM
21400 POPAJ: POP P,A
21500 CPOPJ: POPJ P,
21600 PAGE
21700 ;BIGNUM COPY
21750 .COPY:
21800 COPY: JUMPE A,CPOPJ
21900 HLRZ B,(A)
22000 PUSH P,(B)
22100 HRRZ A,(A)
22200 PUSHJ P,COPY
22300 MOVE B,A
22400 POP P,A
22500 JRST BCONS
22600
22700
22800 ;BIGNUM RECLAIM
22900 RECLAIM:
23000 CAILE A,INUMIN
23100 POPJ P,
23200 EXCH A,F
23300 EXCH A,(F)
23400 HRRZS A
23500 EXCH A,F
23600 EXCH A,(F)
23700 HLRZ B,A ;TYPE
23800 HRRZS A
23900 CAIE B,POSNUM
24000 CAIN B,NEGNUM
24100 JRST UNCONS
24200 POPJ P,
24300
24400 ;BIGNUM UNCONS
24500 UNCONS:
24600 JUMPE A,CPOPJ
24700 HLRZ B,(A)
24800 MOVEM FF,(B)
24900 MOVE FF,B
25000 EXCH A,F
25100 EXCH A,(F)
25200 HRRZS A
25300 JRST UNCONS
25400
25500 ;EVBIG IN LISP HAS JRST BIGEV
25600 BIGEV: CAIE TT,POSNUM
25700 CAIN TT,NEGNUM
25800 POPJ P,
25900 HRRZ AR1,(AR1)
26000 JRST EVBIG+1
26100 PAGE
26200 ;BIGNUM MINUSP
26300 MINSP2: CAIN B,POSNUM
26400 JRST FALSE
26500 JRST TRUE
26600
26700 ;BIGNUM MINUS
26800 MINS2: CAIN B,POSNUM
26900 SKIPA B,[NEGNUM]
27000 ABS2: MOVEI B,POSNUM ;BIGNUM ABS
27100 JRST QCONS
27200
27300 ;COMPARE TWO BIGNUMS A<B
27400 BCMPR: PUSHJ P,BDIF
27500 PUSH P,A
27600 PUSHJ P,MINUSP
27700 EXCH A,(P)
27800 PUSHJ P,RECLAIM
27900 JRST POPAJ
28000
28100 BEQUAL: PUSHJ P,BDIF
28200 POP P,C
28300 CAIN A,INUM0
28400 JRST TRUE
28500 MOVE P,C
28600 PUSHJ P,RECLAIM
28700 JRST FALSE
28800 PAGE
28900 ;DIFFERENCE OF TWO BIGNUMS
29000 BDIF: PUSHJ P,COMPSN ;COMPLEMENT SIGN OF BIGNUM IN B
29100 ;SUM OF TWO BIGNUMS
29200 ;BIGNUMS IN A AND B; SIGN(A) IN T, SIGN(B) IN TT
29300 BPLUS: PUSH P,B
29400 PUSHJ P,COPY
29500 EXCH A,(P)
29600 PUSHJ P,COPY
29700 POP P,C
29800 MOVE B,A
29900 MOVEI A,0
30000 CAME T,TT
30100 JRST BDIF1 ;SIGNS DIFFERENT
30200 PUSH P,T ;SIGN OF RESULT
30300 PUSHJ P,BADD
30400 POP P,B
30500 JRST QCONS
30600
30700 BDIF1: CAIN TT,POSNUM
30800 EXCH B,C
30900 PUSHJ P,BSUB ;POSNUM IN C, NEGNUM IN B
31000 JUMPL B,BDIF3
31100 PUSHJ P,SUPRSS
31200 MOVEI B,POSNUM
31300 JRST MAKBIG
31400
31500 BDIF3: PUSHJ P,COMPLM
31600 MOVEI B,NEGNUM
31700 JRST MAKBIG
31800
31900 BSUB: MOVNI TT,1
32000 MOVSI T,(SUB TT,(B))
32100 JRST BAS
32200
32300 BADD: MOVEI TT,1
32400 MOVSI T,(ADD TT,(B))
32500 PAGE
32600 ;CRY(A)(+ OR -) BIG(B) + BIG(C) → A, SIGN → B.
32700 ;DESTROYS BOTH BIGNUMS
32800
32900 BAS: HRRM TT,BCRY
33000 PUSH P,B
33100 BP2A: HRRM B,BTMP
33200 MOVS B,(B)
33300 HLRZ TT,(C)
33400 EXCH TT,FF
33500 EXCH TT,(FF) ;RECLAIM FULL WORD
33600 EXCH C,F
33700 EXCH C,(F) ;RECLAIM FREE WORD
33800 ADD TT,A
33900 XCT T ;BIG(C) (+ OR -) BIG (B)
34000 MOVEI A,0
34100 TLZE TT,SIGN ;TURN OFF HIGH BIT
34200 BCRY: HRREI A,. ;SET CARRY IF OVERFLOW OR NEGATIVE
34300 BP2B: MOVEM TT,(B)
34400 HLRZS B
34500 HRRZS C
34600 JUMPE B,BP2F ;END OF B
34700 JUMPN C,BP2A
34800 JRST BP2D ;FINISH WITH CARRY (+ OR -) BIG(B)
34900
35000 BP2F: JUMPE C,BP2H ;END OF C ALSO
35100 EXCH B,C
35200 HRRM B,@BTMP ;RPLACD END OF BIG(B) WITH REST OF C
35300 MOVSI T,(ADD TT,(B)) ;FINISH WITH BIG(C) + CARRY
35400 BP2D: HRRM B,BTMP
35500 MOVS B,(B)
35600 MOVE TT,A
35700 XCT T ;CARRY (+ OR -) INTEGER
35800 JUMPL TT,BP2K
35900 MOVEM TT,(B)
36000 CAME T,[SUB TT,(B)]
36100 JRST POSXIT ;CAN QUIT NOW
36200 MOVEI A,0 ;TURN OFF CARRY
36300 JRST BP2L ;CONTINUE TO NEGATE
36400
36500 BP2K: HRRE A,BCRY
36600 TLZ TT,SIGN ;MAKE HIGH BIT ZERO
36700 MOVEM TT,(B)
36800 BP2L: HLRZS B
36900 JUMPN B,BP2D
37000 BP2H: JUMPLE A,XIT ;NO CARRY
37100 PUSHJ P,BNCONS
37200 BTMP: HRRM A,. ;RPLACD END OF BIGNUM WITH CARRY
37300 POSXIT: MOVEI B,0 ;SIGN POSITIVE
37400 JRST POPAJ
37500
37600 XIT: MOVE B,A ;SIGN IN B
37700 JRST POPAJ
37800 PAGE
37900 ;SUPPRESS LEADING ZEROS FROM BIGNUM
38000 SUPRSS: SKIPA C,[JRST COMPL7]
38100 ;COMPLEMENT BIGNUM (2↑35 COMPLEMENT)
38200 COMPLM: MOVSI C,(SUBM T,(B))
38300 JUMPE A,CPOPJ
38400 PUSH P,A
38500 HRLZI T,SIGN
38600 MOVEI TT,0
38700 COMPL4: MOVS B,(A)
38800 SKIPN (B)
38900 JUMPE TT,COMPL3
39000 XCT C
39100 HRLOI T,SIGN-1
39200 COMPL7: SKIPE (B)
39300 MOVEM A,TT
39400 COMPL3: HLRZ A,B
39500 JUMPN A,COMPL4 ;CONTINUE
39600 JUMPE TT,COMPL5 ;ALL ZEROS
39700 HRRZ A,(TT)
39800 HLLZS (TT) ;RPLACD HIGH ORDER NON-ZERO WITH NIL
39900 COMPL6: PUSHJ P,UNCONS ;UNCONS LEADING ZEROS
40000 JRST POPAJ
40100
40200 COMPL5: EXCH A,(P)
40300 JRST COMPL6
40400
40500 ;SIGN(TT)⊗SIGN(T) → TT
40600 MQSIGN: CAIN T,POSNUM
40700 JRST CPOPJ
40800 ;-SIGN(TT) → TT
40900 COMPSN: CAIN TT,POSNUM
41000 SKIPA TT,[NEGNUM]
41100 MOVEI TT,POSNUM
41200 POPJ P,
41300 PAGE
41400 ;BIGNUM MULTIPLY
41500 ;BIG (A) * BIG (B) → A, SIGNS IN T,TT
41600 BTIMES: PUSHJ P,MQSIGN
41700 PUSH P,TT ;SAVE SIGN OF RESULT
41800 PUSHJ P,BMUL
41900 POP P,B
42000 JRST MAKBIG
42100
42200 ;0(P) IS PARTIAL RESULT
42300 ;-1(P) IS REMAINING REVERSED MULTIPLIER
42400 ;-2(P) IS MULTIPLICAND
42500
42600 BMUL: PUSH P,B
42700 PUSHJ P,REVERSE
42800 PUSH P,A
42900 MOVEI A,0
43000 PUSH P,A
43100 BTLOOP: SKIPN C,-1(P)
43200 JRST BTEND ;END OF MULTIPLIER
43300 JUMPE A,BTLP2 ;FIRST TIME
43400 MOVE B,A
43500 PUSHJ P,FWCONS-1
43600 PUSHJ P,CONS ;INCREASE LENGTH OF PRODUCT
43700 BTLP2: MOVEM A,(P)
43800 MOVE A,-2(P)
43900 PUSHJ P,COPY
44000 MOVS B,(C) ;NEXT MULTIPLIER DIGIT
44100 MOVE C,A
44200 HLRZM B,-1(P)
44300 MOVE B,(B)
44400 MOVEI A,0
44500 PUSHJ P,BTIME1
44600 MOVE C,(P)
44700 JUMPE C,BTLOOP ;NO ADD NEEDED ON FIRST TIME
44800 MOVE B,A
44900 MOVEI A,0
45000 PUSHJ P,BADD
45100 JRST BTLOOP
45200
45300 BTEND: SUB P,[XWD 3,3]
45400 JRST SUPRSS
45500
45600 PAGE
45700 ;EXTENSIONS OF INTERPRETER ROUTINES AND TESTS
45800
45900 ;ADDITION TO NUMVAL. NUMV4 IN LISP CHANGED TO JRST NUMVB
46000 NUMVB: CAIE B,POSNUM
46100 CAIN B,NEGNUM
46200 JRST NUMVD2
46300 MOVE A,AR1
46400 JRST NUMV2 ;PRINT ERROR MESSAGE
46500
46600 NUMVD2: POP P,C ;ADDRESS OF (PUSHJ P,NUMVAL) +1
46700 HLRZ C,(C)
46800 CAIN C,(JUMPN A,) ;ZEROP
46900 JRST FALSE
47000 CAIN C,(JUMPGE A,) ;MINUSP
47100 JRST MINSP2
47200 CAIN C,(MOVNS) ;MINUS
47300 JRST MINS2
47400 CAIN C,(MOVMS) ;ABS
47500 JRST ABS2
47600 CAIN C,(CAIE B,) ;FIX
47700 JRST POPAJ
47800 POPJ P, ;**************** WAS A HALT <A.HEARN>
47900 ;EXTENSION TO NUMBERP. NUMBRP4 IN LISP CHANGED TO JRST BIGNP
48000 BIGNP: CAIE A,POSNUM
48100 CAIN A,NEGNUM
48200 JRST TRUE
48300 JRST FALSE
48400 PAGE
48500 ;EXTENSION TO OP. OPOV IN LISP CHANGED TO JFCL 10,FIXOVL
48600 FIXOVL: HLRZ C,(C)
48700 CAIN C,(IMUL A,)
48800 JRST REMUL ;TIMES OVERFLOWED. RECOMPUTE
48810 JUMPE A,[SETZ B,
48820 SETO TT, ;NEGATIVE
48830 MOVEI A,Z
48840 JRST FIXOVZ]
48900 TLC A,SIGN ;ALL OTHER CASES JUST OVERFLOWED 1 BIT
49000 MOVM B,A
49100 MOVE TT,A
49200 MOVEI A,1
49300 FIXOVZ: PUSHJ P,MKBG
49400 JRST QCONS
49500
49600 REMUL: MOVE A,AR1
49700 MOVEI B,FIXNUM
49800 MOVEI T,FIXNUM
49900 PUSHJ P,BIGTST
50000 JRST BTIMES ;USE THE BIGNUM MULTIPLICATION
50100
50200 ;EXTENSION TO OP. NUMV3 CHANGED TO JRST BIGDIS
50300 ;BIGDIS DETERMINES THE BIGNUM OPERATION TO BE PERFORMED
50400 BIGDIS: CAIE T,FLONUM
50500 CAIN B,FLONUM
50600 JRST FLOBIG ;OPERATION WITH FLT PT OPERAND
50700 PUSHJ P,BIGTST
50800 HLRZ C,(C)
50900 CAIN C,(ADD A,) ;PLUS
51000 JRST BPLUS
51100 CAIN C,(SUB A,) ;DIF
51200 JRST BDIF
51300 CAIN C,(IMUL A,) ;TIMES
51400 JRST BTIMES
51500 CAIN C,(IDIV A,) ;QUOTIENT
51600 JRST BQUO
51700 CAIN C,(JRST) ;LESSP OR GREATERP
51800 JRST BCMPR
51900 CAIN C,(JUMPN 0,) ;DIVIDE
52000 JRST BDIV
52100 CAIN C,(JUMPA) ;GCD
52200 JRST GCD
52300 CAIN C,(JUMPL) ;EQUAL
52400 JRST BEQUAL
52500 HALT ;TEMPROARY
52600 PAGE
52700 ;TRANSFORMS GENERAL NUMBERS IN (A,T),(TT,B)
52800 ;INTO BIGNUMS IN (A,T),(B,TT), VALUES IN A,B; SIGNS IN T,TT.
52900 BIGTST: EXCH B,T ;FUNNY AC USAGE IN LISP
53000 PUSH P,T
53100 PUSH P,TT
53200 PUSHJ P,BIGSUB ;CONVERT NUMBER ORIGINALLY IN A,T
53300 EXCH B,-1(P)
53400 EXCH A,(P)
53500 PUSHJ P,BIGSUB ;CONVERT NUMBER ORIGINALLY IN TT,B
53600 MOVE TT,B
53700 MOVE B,A
53800 POP P,A
53900 POP P,T
54000 POPJ P,
54100
54200 BIGSUB: CAIE B,POSNUM
54300 CAIN B,NEGNUM
54400 POPJ P, ;NO CONVERSION NECESSARY
54500 CAIE B,FIXNUM
54600 JRST NUMV2 ;CHECK FOR FLONUM
54700 MOVEI B,0
54800 MOVE TT,A ;GET VALUE OF NUMBER
54900 MOVM A,TT
55000 JUMPGE A,BIGSRT
55100 MOVEI A,1 ;BASTARD CASE OF -2↑35
55200 MKBG: PUSHJ P,MKBIG
55300 JRST BIGSND
55400
55500 BIGSRT: PUSHJ P,BCONS
55600 BIGSND: SKIPGE TT
55700 SKIPA B,[NEGNUM]
55800 MOVEI B,POSNUM
55900 POPJ P,
56000
56100 MKBIG: PUSH P,B
56200 PUSHJ P,BNCONS
56300 MOVE B,A
56400 POP P,A
56500 JRST BCONS
56600 PAGE
56700 ;MAKE A LISP NUMBER FROM BIGNUM -- A IS LIST, B IS SIGN
56800 MAKBIG: JUMPE A,FIX1A ;NULL LIST PRODUCES ZERO
56900 HRRZ C,(A)
57000 JUMPN C,QCONS ;A REAL BIGNUM
57100 HLRZ C,(A) ;ONLY ONE WORD OF PRECISION
57200 MOVE C,(C)
57300 CAIE B,POSNUM
57400 MOVNS C ;NEGATIVE
57500 PUSHJ P,UNCONS
57600 MOVE A,C
57700 JRST FIX1A
57800 PAGE
57900 FLOBIG: CAIE T,FLONUM
58000 JRST FLBG2
58100 MOVE A,(A)
58200 EXCH A,TT
58300 EXCH B,T
58400 PUSHJ P,BFLT
58500 EXCH A,TT
58600 JRST OPR
58700
58800 FLBG2: PUSHJ P,BFLT
58900 MOVE TT,(TT)
59000 JRST OPR
59100
59200 ;MAKE A FLOATING PT NUMBER OUT OF A BIGNUM
59300 BFLT: PUSH P,C
59400 PUSH P,T
59500 CAIE T,POSNUM
59600 CAIN T,NEGNUM
59700 SKIPA T,[-200]
59800 JRST NUMV2
59900 BFLT2: MOVE C,B
60000 HLRZ B,(A)
60100 HRRZ A,(A)
60200 ADDI T,43
60300 JUMPN A,BFLT2 ;FIND LAST TWO WORDS OF BIGNUM
60400 MOVE B,(B)
60500 MOVE C,(C)
60600 BFLT3: TLNE B,SIGN/2
60700 JRST BFLT4
60800 ASHC B,1
60900 SOJA T,BFLT3 ;NORMALIZE B,C
61000 BFLT4: JUMPGE T,FLOOV
61100 ASH B,-10
61200 DPB T,[POINT 8,B,8]
61300 MOVE A,B
61400 POP P,T
61500 POP P,C
61600 CAIE T,POSNUM
61700 MOVNS A
61800 POPJ P,
61900
62000 ;MAKE A BIGNUM FROM A FLT PT NUMBER
62100 BFIX: MOVE A,(P)
62200 PUSHJ P,NUMVAL
62300 MOVMS A
62400 MULI A,400
62500 MOVEI C,-243(A) ;#LEFT SHIFTS NEEDED
62600 IDIVI C,43 ;C←#EXTRA WORDS-1, D←#SHIFTS
62700 MOVEI A,0
62800 ASHC A,(C+1)
62900 PUSH P,B
63000 PUSHJ P,BNCONS
63100 MOVE B,A
63200 POP P,A
63300 PUSHJ P,BCONS
63400 SOJL C,BFIX2
63500 MOVE B,A
63600 MOVEI A,0
63700 PUSHJ P,BCONS
63800 SOJGE C,.-3
63900 BFIX2: POP P,TT
64000 PUSHJ P,BIGSND
64100 JRST QCONS
64200
64300 PAGE
64400 ;BIGNUM DIVIDE
64500 BDIV: PUSHJ P,MQSIGN ;COMPLEMENT SIGN OF TT IF T IS NEGNUM
64600 PUSH P,T ;SIGN OF REMAINDER
64700 PUSH P,TT ;SIGN OF QUOTIENT
64800 PUSHJ P,DIVSUB
64900 BDIV2: EXCH B,(P)
65000 PUSHJ P,MAKBIG ;QUOTIENT
65100 MOVE B,-1(P)
65200 MOVEM A,-1(P)
65300 POP P,A
65400 PUSHJ P,MAKBIG ;REMAINDER
65500 POP P,B
65600 JRST XCONS
65700
65800 BQUO: PUSHJ P,MQSIGN
65900 PUSH P,TT
66000 PUSHJ P,DIVSUB
66100 PUSH P,A
66200 MOVE A,B
66300 PUSHJ P,UNCONS
66400 POP P,A
66500 POP P,B
66600 JRST MAKBIG
66700
66800 DIVSUB: HRRZ C,(B)
66900 JUMPN C,DIV1
67000 ;NULL(CDR B) MEANS SINGLE LENGTH DIVISOR
67100 BQUO1: PUSH P,B
67200 PUSHJ P,COPY
67300 POP P,B
67400 HLRZ B,(B)
67500 MOVE B,(B)
67600 PUSHJ P,Q1
67700 PUSH P,B ;QUOTIENT
67800 PUSHJ P,BNCONS
67900 MOVE B,A
68000 JRST POPAJ
68100
68200 PAGE
68300 ;DIV1 DOES LONG DIVISION OF X/Y
68400 ;ENTER WITH X IN A, Y IN B.
68500 DIV1: PUSH P,A ;X
68600 PUSH P,B ;Y
68700 MOVE A,B
68800 PUSHJ P,HIDIG
68900 HRLOI A,SIGN/2-1
69000 IDIV A,(C) ;(BETA/2-1)/Y[N-1]+1
69100 ADDI A,1
69200 MOVEM A,SCALE#
69300 MOVE B,A
69400 MOVE A,(P) ;Y - DIVISOR
69500 PUSHJ P,BTIME0 ;SCALE*Y
69600 MOVEM A,V ;SCALED DIVISOR
69700 MOVEM A,(P) ;PROTECT V FROM GC
69800 PUSHJ P,HIDIG
69900 POP C,VH ;V[N-1]
70000 POP C,VH1 ;V[N-2]
70100 MOVE A,-1(P) ;X - NUMERATOR
70200 PUSHJ P,COPY
70300 PUSHJ P,EXTND
70400 MOVE B,SCALE
70500 MOVE C,A
70600 PUSHJ P,BTIME1-1 ;SCALE*X -- SCALED NUMERATOR
70700 MOVEM A,-1(P) ;U
70800 PUSH P,[NIL]
70900 HRRZM P,QUO# ;POINTER TO QUOTIENT LIST
71000 PUSHJ P,LENGTH
71100 PUSH P,A
71200 MOVE A,V#
71300 PUSHJ P,LENGTH
71400 POP P,B
71500 SUB B,A ;LENGTH(U)-LENGTH(V)
71600 MOVE A,-2(P) ;U
71700 JUMPLE B,DIV1X ;SPECIAL CASE OF U<V
71800 PUSHJ P,DIV2 ;CARRY OUT DIVISION WITH PARAMETERS
71900 DIV1X: PUSHJ P,SUPRSS ;SUPPRESS LEADING ZEROS OF REMAINDER
72000 JUMPE A,DIV1Y ;ZERO REMAINDER
72100 MOVE B,SCALE
72200 PUSHJ P,Q1 ;U/SCALE - FINAL REMAINDER IN B
72300 MOVE A,B
72400 DIV1Y: EXCH A,(P)
72500 PUSHJ P,SUPRSS ;SUPPRESS LEADING ZEROS IN QUOTIENT
72600 POP P,B
72700 SUB P,[XWD 2,2]
72800 POPJ P,
72900
73000 ;RECURSIVE FUNCTION TO POSITION V PROPERLY WITH RESPECT TO U.
73100 ; ON SUCCESSIVE CALLS TO DIV3 WHICH CALCULATES QUOTIENT DIGITS.
73200 ;ENTER DIV2 WITH U IN A, N IN B. N= LENGTH(U)-LENGTH(V)-1.
73300
73400 DIV2: SOJLE B,DIV3
73500 PUSH P,A ;U
73600 HRRZ A,(A)
73700 PUSHJ P,DIV2
73800 HRRM A,@(P) ;(RPLACD U,(DIV3(CDR U)))
73900 POP P,A
74000 JRST DIV3
74100 PAGE
74200 ;ENTER WITH U[J] IN A
74300
74400 DIV3: PUSH P,A ;UJ
74500 PUSHJ P,HIDIG
74600 POP C,A ;UH
74700 CAML A,VH#
74800 JRST DIVCS1 ;STRANGE CASE WHEN UH≥VH
74900 POP C,B ;UH1
75000 DIV A,VH ;(UH*BETA+UH1)/VH
75100 PUSH P,A ;QUOTIENT DIGIT
75200 L1: MOVEM B,REM# ;REMAINDER
75300 MUL A,VH1#
75400 SUB A,REM ;(VH1*QUO)-BETA*REM
75500 CAMGE B,(C) ;UH2
75600 SUBI A,1
75700 JUMPG A,DIVCS2 ;QUOTIENT TOO BIG
75800 L4: MOVE A,V
75900 MOVE B,(P) ;QUOTIENT DIGIT
76000 PUSHJ P,BTIME0 ;Q*V
76100 MOVE C,-1(P) ;UJ
76200 MOVE B,A
76300 MOVEI A,0
76400 PUSHJ P,BSUB ;UJ-Q*V
76500 JUMPL B,DIVCS3 ;QUOTIENT TOO BIG
76600 L3: MOVEM A,-1(P) ;NEW UJ
76700 POP P,A ;QUOTIENT DIGIT
76800 MOVE B,@QUO
76900 PUSHJ P,BCONS
77000 MOVEM A,@QUO ;NEW QUOTIENT LIST
77100 MOVE A,(P)
77200 PUSHJ P,DIVSRT ;SHORTEN UJ BY ONE DIGIT
77300 JRST POPAJ
77400 PAGE
77500 ;SPECIAL CASE OF UH≥VH
77600 DIVCS1: HRLOI A,SIGN-1 ;BETA-1
77700 PUSH P,A
77800 POP C,B ;UH1
77900 ADD B,VH ;R←UH1+VH
78000 JUMPL B,L4
78100 JRST L1
78200
78300 ;SPECIAL CASE CORRECTION FOR QUOTIENT
78400 DIVCS2: SOS A,(P) ;QUOTIENT←QUOTIENT-1
78500 MOVE B,REM
78600 ADD B,VH ;R←R+VH
78700 JRST L1
78800
78900 ;SPECIAL CASE OF QUOTIENT TOO LARGE
79000 DIVCS3: SOS (P) ;QUOTIENT←QUOTIENT-1
79100 PUSH P,A
79200 MOVE A,V
79300 PUSHJ P,COPY
79400 MOVE C,A
79500 POP P,B
79600 MOVEI A,0
79700 PUSHJ P,BADD ;U←U+V
79800 MOVEM A,-1(P)
79900 PUSHJ P,DIVSRT ;SHORTEN OVERFLOWED DIGIT
80000 JRST L3+1
80100 PAGE
80200 ;PUSHES SUCCESSIVE DIGITS OF LIST IN A ONTO PDL
80300 ;RETURNS C POINTING TO PDL LOCATION OF LAST DIGIT
80400 HIDIG: MOVE C,P
80500 MOVS B,(A)
80600 PUSH P,(B)
80700 HLRZ A,B
80800 JUMPN A,HIDIG+1
80900 EXCH C,P
81000 POPJ P,
81100
81200 ;SHORTEN LIST BY ONE
81300 DIVSRT: MOVE C,A
81400 HRRZ A,(A)
81500 HRRZ B,(A) ;CDDR
81600 JUMPN B,.-3
81700 HLLZS (C) ;NULL (CDDR C) => RPLACD(C NIL)
81800 HLRZ B,(A)
81900 JRST UNCONS
82000
82100 ;LENGTHEN LIST BY ONE
82200 EXTND: PUSH P,A
82300 PUSHJ P,LAST
82400 MOVE T,A
82500 PUSHJ P,B0CONS
82600 HRRM A,(T)
82700 JRST POPAJ
82800 PAGE
82900 GA==4
83000 GB==5
83100 GC==6
83200 GD==7
83300 UP==10
83400 VP==11
83500 Q==12
83600 ;BIGNUM GCD
83700 GCD: PUSH P,B
83800 PUSHJ P,COPY
83900 EXCH A,(P) ;V
84000 PUSHJ P,COPY
84100 PUSH P,A ;U
84200 PUSHJ P,COPY
84300 MOVE C,A
84400 MOVE A,-1(P)
84500 PUSHJ P,COPY
84600 MOVE B,A ;U
84700 MOVEI A,0
84800 PUSHJ P,BSUB ;V-U
84900 PUSH P,B
85000 PUSHJ P,BSUBND
85100 JUMPE A,GCDSC1 ;U=V
85200 PUSHJ P,UNCONS
85300 POP P,B
85400 JUMPGE B,GCD2 ;U≥V
85500 MOVE A,(P)
85600 EXCH A,-1(P)
85700 MOVEM A,(P)
85800 PAGE
85900 ;NOW V<U V IN -1(P), U IN (P)
86000 GCD2: MOVE A,-1(P)
86100 JUMPE A,GCDEND ;V IS ZERO
86200 HRRZ B,(A)
86300 JUMPE B,GCDSING ;V IS SINGLE PRECISION
86400 PUSHJ P,LENGTH ;LENGTH (V)
86500 MOVE T,A
86600 MOVE A,(P) ;U
86700 PUSHJ P,LENGTH
86800 SUB A,T ;L(U)-L(V)
86900 JUMPE A,GCD4
87000 SOJN A,GCD7A ;>1
87100 MOVE A,-1(P) ;V
87200 PUSHJ P,EXTND ;LENGTHEN V BY ONE HIGH ORDER ZERO
87300 GCD4: MOVE A,(P) ;U
87400 PUSHJ P,HIDIG
87500 HRLOI A,SIGN/2-1 ;BETA/2-1
87600 IDIV A,(C) ;(BETA/2-1)/U[N-1]+1
87700 ADDI A,1
87800 MOVEM A,SCALE
87900 PUSHJ P,GCSB
88000 MOVE UP,A ;SCALE*UH
88100 MOVE A,-1(P) ;V
88200 PUSHJ P,HIDIG
88300 PUSHJ P,GCSB
88400 MOVE VP,A ;SCALE*VH
88500 MOVEI GA,1
88600 MOVEI GD,1
88700 SETZB GC,GB
88800 PAGE
88900 GCD5: MOVE A,UP
89000 ADD A,GA
89100 MOVE B,VP
89200 ADD B,GC
89300 JUMPE B,GCD7
89400 JUMPL A,GCD5X ;OVERFLOW CASE
89500 IDIV A,B ;(U'+A)/(V'+C)
89600 GCD5A: MOVE Q,A
89700 MOVE A,UP
89800 ADD A,GB
89900 MOVE B,VP
90000 ADD B,GD
90100 JUMPE B,GCD7
90200 SKIPG B
90300 TDZA A,A ;SPECIAL CASE OF V'+D = BETA
90400 IDIV A,B ;(U'+B)/(V'+D)
90500 CAME A,Q
90600 JRST GCD7
90700 MOVE A,GC
90800 EXCH GA,GC ;A'←C
90900 IMUL A,Q
91000 SUB GC,A ;C'←A-Q*C
91100 MOVE A,GD
91200 EXCH GB,GD ;B'←D
91300 IMUL A,Q
91400 SUB GD,A ;D'←B-Q*D
91500 MOVE A,VP
91600 EXCH UP,VP ;UP'←VP
91700 IMUL A,Q
91800 SUB VP,A ;VP'←UP-Q*VP
91900 JRST GCD5
92000 PAGE
92100 ;SPECIAL CASE WHEN U'+A=BETA
92200 GCD5X: MOVEI A,1
92300 MOVE C,B
92400 MOVEI B,0
92500 DIV A,C
92600 JRST GCD5A
92700
92800 GCD7: JUMPE GB,GCD7A
92900 MOVE A,(P) ;U
93000 MOVE B,-1(P) ;V
93100 PUSH P,GC
93200 PUSH P,GD
93300 PUSHJ P,GCDSB ;A*U+B*V
93400 POP P,GB
93500 POP P,GA
93600 EXCH A,(P) ;U
93700 MOVE B,-1(P)
93800 PUSHJ P,GCDSB ;C*U+D*V
93900 MOVEM A,-1(P) ;V
94000 JRST GCD2
94100
94200 GCDSB: PUSH P,GA
94300 PUSH P,GB
94400 PUSH P,B
94500 MOVM B,GA
94600 PUSHJ P,BTIME0
94700 EXCH A,(P) ;B
94800 MOVM B,-1(P) ;GB
94900 PUSHJ P,BTIME0
95000 POP P,B ;A*GA
95100 POP P,GA
95200 POP P,GB
95300 XOR GA,GB
95400 MOVE C,A
95500 MOVEI A,0
95600 JUMPGE GA,BADD ;SIGNS SAME
95700 PUSHJ P,BSUB ;SIGNS DIFFERENT
95800 BSUBND: JUMPGE B,SUPRSS
95900 JRST COMPLM
96000
96100 GCD7A: MOVE A,-1(P)
96200 PUSHJ P,SUPRSS
96300 MOVE B,A
96400 MOVE A,(P)
96500 PUSHJ P,DIV1 ;U/V
96600 EXCH B,-1(P) ;V←REMAINDER
96700 MOVEM B,(P) ;U←V
96800 PUSHJ P,UNCONS ;DONT NEED QUOTIENT
96900 JRST GCD2
97000 PAGE
97100 GCDSING:
97200 POP P,A ;U
97300 MOVE B,(P) ;V - SINGLE PRECISION
97400 HLRZ B,(B)
97500 MOVE B,(B)
97600 MOVEM B,(P)
97700 PUSHJ P,Q1 ;U MOD V → A
97800 POP P,B ;A < B
97900 JUMPE A,GCDS2
98000 ;SINGLE PRECISION GCD
98100 IDIV B,A
98200 MOVE B,A
98300 MOVE A,C
98400 JUMPN A,.-3
98500 GCDS2: MOVE A,B
98600 JRST FIX1A
98700
98800 GCSB: MOVE A,-1(C)
98900 MUL A,SCALE
99000 MOVE B,A
99100 MOVE A,(C)
99200 IMUL A,SCALE
99300 ADD A,B
99400 POPJ P,
99500 PAGE
99600 GCDSC1: SUB P,[XWD 2,2]
99700 POP P,A
99800 MOVEI B,POSNUM
99900 JRST MAKBIG
00100
00200 GCDEND: POP P,A ;U IS RESULT
00300 SUB P,[XWD 1,1]
00400 MOVEI B,POSNUM
00500 JRST MAKBIG
00600
00700 END